#include "stdafx.h"

typedef std::vector<Vector2f> vv2;
struct shape_util
{
    //sf::ConvexShape Polygon;
    //sf::Shape Polygon;
    sf::RenderWindow * window;
    sf_cons console;
    map<string, sf::Sprite> sprites;
    map<string, sf::Texture> textures;
    //std::vector <Vector2f> points;
    struct shape
    {
        vv2 points;
        sf::ConvexShape Polygon;
        vector<RectangleShape> gizmos;
    };
    std::vector<shape> shapes;
    size_t current;
    Vector2f mouse;
    RectangleShape gizmo;
    Vector2f giz_off;
    void init()
    {
        current = -1;
        gizmo.setFillColor(Color(0,0,0,255));
        gizmo.setSize(Vector2f(4,4));
        giz_off = Vector2f(-2,-2);
        
        window = new sf::RenderWindow (sf::VideoMode(800, 600), "procedural shape utility");

        window->setMouseCursorVisible(false);

        textures["cursor"] = sf::Texture();
        textures["bg"] = sf::Texture();
        sprites["cursor"] = sf::Sprite();
        sprites["bg"] = sf::Sprite();
        //system("pwd");
#ifdef __APPLE__
        textures["bg"].loadFromFile(resourcePath()+"grid.png");
        textures["cursor"].loadFromFile(resourcePath()+"cursor.png");
#else
        textures["bg"].loadFromFile("grid.png");
        textures["cursor"].loadFromFile("cursor.png");
#endif
        sprites["bg"].setTexture(textures["bg"]);
        sprites["cursor"].setTexture(textures["cursor"]);

        beginshape();
    }
    ~shape_util() { delete window; }
    void handle_loop()
    {
        while (window->isOpen())
        {
            sf::Event event_;
            while (window->pollEvent(event_))
            {
                if (event_.type == sf::Event::Closed ||
                    (event_.type == sf::Event::KeyPressed && event_.key.code == Keyboard::Escape))
                    window->close();
                if(event_.type == sf::Event::MouseMoved)
                {
                    mouse = Vector2f(float(event_.mouseMove.x), float(event_.mouseMove.y));
                    sprites["cursor"].setPosition(mouse);
                    if(shapes[current].Polygon.getPointCount() > 0)
                    shapes[current].Polygon.setPoint(shapes[current].Polygon.getPointCount()-1, mouse);
                }
                if(event_.type == sf::Event::MouseButtonPressed)
                {
                    // we clear and recopy points from the polygons
                    shapes[current].points.clear();
                    FOR(shapes[current].Polygon.getPointCount())
                        shapes[current].points.push_back(shapes[current].Polygon.getPoint(i));
                    
                    // we add a point and it's gizmo to show it
                    shapes[current].points.push_back(mouse);
                    shapes[current].gizmos.push_back(gizmo);
                    shapes.back().gizmos.back().setPosition(mouse+giz_off);
                    
                    // we rewrite points. yeah, private stuff is a bitch
                    shapes[current].Polygon.setPointCount(shapes[current].points.size());
                    FOR(shapes[0].points.size())
                        shapes[current].Polygon.setPoint(i, shapes[0].points[i]);

                    {
                        size_t u = shapes[current].Polygon.getPointCount();
                        cout << "point begin" << endl;
                        FOR(u)
                            cout << "    point " << i << ": " <<
                                shapes[current].Polygon.getPoint(i).x << " " << shapes[current].Polygon.getPoint(i).y << endl;
                        cout << "-------" << endl;
                        u = shapes[current].points.size();
                        FOR(u) 
                            cout << "    point " << i << ": " <<
                            shapes[current].points[i].x << " " << shapes[current].points[i].y << endl;
                        cout << "point end" << endl;
                    }

                }
                if(event_.type == sf::Event::KeyPressed)
                    switch (event_.key.code)
                    {
                        case sf::Keyboard::Num1:
                            
                            break;
                        case sf::Keyboard::Num2:
                            finish();
                            break;
                        case sf::Keyboard::Num3:
                            write();
                            break;
                            
                        default:
                            break;
                    }
                window->clear();
                window->draw(sprites["bg"]);
                for(auto a = shapes.begin(); a != shapes.end(); ++a)
                {
                    window->draw(a->Polygon);
                    for (auto b = a->gizmos.begin(); b!=a->gizmos.end(); ++b)
                        window->draw(*b);
                }
                //window->draw(Polygon);
                window->draw(sprites["cursor"]);
                window->display();
            }
        }
    }
    void beginshape()
    {
        shapes.push_back(shape());
        current++;
        shapes[current].Polygon.setFillColor(sf::Color(0,0,0,0));
        shapes[current].Polygon.setOutlineColor(sf::Color(30,100,200));
        shapes[current].Polygon.setOutlineThickness(1.5);
    }
    void finish()
    {
        shapes.push_back(shape());
        current++;
    }
    void write()
    {
        ofstream f;
        f.open("shape.txt");
        if(!f.is_open())
        {
            console.push_text("could not open file");
            return;
        }
                
        FOR(shapes[current].points.size())
            f << shapes[current].points[i].x << " " << shapes[current].points[i].y << endl;

        f.close();
        console.push_text("wrote "+TO_STR(shapes[current].points.size()));
    }
};